#include<iostream>
using namespace std;

// 抽象类:不能实例化出对象
// 间接强制派生类重写虚函数
// override 已经重写了，帮助检查语法是否有问题
//class Car
//{
//public:
//	// 纯虚函数
//	virtual void Drive() = 0;
//}; 
//
//class Benz :public Car
//{
//public:
//	virtual void Drive()
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//
//class BMW :public Car
//{
//public:
//	virtual void Drive()
//	{
//		cout << "BMW-操控" << endl;
//	}
//};
//
//int main()
//{
//	//Car c;
//	Benz b1;
//	BMW b2;
//
//	Car* ptr = &b1;
//	ptr->Drive();
//	
//	ptr = &b2;
//	ptr->Drive();
//
//	return 0;
//}


class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};

class Student : public Person {
public:
	virtual void BuyTicket() { cout << "买票-半价" << endl; }
};

// 多态调用：运行时，到指向对象的虚表中找虚函数调用，指向父类调用父类的虚函数，指向子类调用子类的虚函数
// 普通调用：编译时，调用对象是哪个类型，就调用他的函数
// 虚表：虚函数表，存的虚函数，目标实现多态
// 虚基表：存的当前位置距离虚基类部分的偏移量，解决菱形继承数据冗余和二义性
void Func(Person& p)
{
	p.BuyTicket();
}

// 进程-> 指令
// 类->实例化对象->指令
// 函数->指令

// 虚函数跟普通函数一样，都是存在代码段，不是存在虚表的
// 虚表中存的仅仅是虚函数的地址
// 虚表存在哪个内存区域的？栈  堆  常量区  静态区 
//
//int main()
//{
//	Person Mike;
//	Func(Mike);
//
//	Student Johnson;
//	Func(Johnson);
//
//	Person p1;
//	Person p2;
//
//	return 0;
//}

//int main()
//{
//	int i = 0;
//	static int j = 1;
//	int* p1 = new int;
//	const char* p2 = "xxxxxxxx";
//	printf("栈:%p\n", &i);
//	printf("静态区:%p\n", &j);
//	printf("堆:%p\n", p1);
//	printf("常量区:%p\n", p2);
//
//	Person p;
//	Student s;
//	Person* p3 = &p;
//	Student* p4 = &s;
//
//	printf("Person虚表地址:%p\n", *(int*)p3);
//	printf("Student虚表地址:%p\n", *(int*)p4);
//
//	return 0;
//}

//class Base {
//public:
//	virtual void func1() { cout << "Base::func1" << endl; }
//	virtual void func2() { cout << "Base::func2" << endl; }
//private:
//	int a;
//};
//
//class Derive :public Base {
//public:
//	Derive()
//	{}
//
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//	virtual void func4() { cout << "Derive::func4" << endl; }
//private:
//	int b = 0;
//};
//
typedef void(*VFPTR) ();
void PrintVTable(VFPTR vTable[])
{
	// 依次取虚表中的虚函数指针打印并调用。调用就可以看出存的是哪个函数
	cout << " 虚表地址>" << vTable << endl;
	for (int i = 0; vTable[i] != nullptr; ++i)
	{
		printf(" 第%d个虚函数地址 :0X%p,->", i, vTable[i]);
		VFPTR f = vTable[i];
		f();
	}
	cout << endl;
}
//
//int main()
//{
//	Base b;
//	Derive d;
//	
//	VFPTR * vTableb = (VFPTR*)(*(int*)&b);
//	PrintVTable(vTableb);
//	VFPTR* vTabled = (VFPTR*)(*(int*)&d);
//	PrintVTable(vTabled);
//
//	return 0;
//}

/////////////////////////////////////////////////////////////////////////////////
// 多继承
class Base1 {
public:
	virtual void func1() { cout << "Base1::func1" << endl; }
	virtual void func2() { cout << "Base1::func2" << endl; }
private:
	int b1;
};

class Base2 {
public:
	virtual void func1() { cout << "Base2::func1" << endl; }
	virtual void func2() { cout << "Base2::func2" << endl; }
private:
	int b2;
};

class Derive : public Base1, public Base2 {
public:
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func3" << endl; }
private:
	int d1;
};

//int main()
//{
//	Derive d;
//	cout << sizeof(Derive) << endl;
//
//	VFPTR* vTableb1 = (VFPTR*)(*(int*)&d);
//	PrintVTable(vTableb1);
//
//	//VFPTR* vTableb2 = (VFPTR*)(*(int*)((char*)&d + sizeof(Base1)));
//
//	Base2* ptr = &d;
//	VFPTR* vTableb2 = (VFPTR*)(*(int*)(ptr));
//	PrintVTable(vTableb2);
//
//	return 0;
//}

//class A
//{
//public:
//
//	virtual void func1() { cout << "A::func1" << endl; }
//
//	int _a;
//};
//
////class B : public A
//class B : virtual public A
//{
//public:
//	virtual void func2() { cout << "B::func2" << endl; }
//
//	int _b;
//};
//
////class C : public A
//class C : virtual public A
//{
//public:
//	virtual void func3() { cout << "C::func3" << endl; }
//
//	int _c;
//};
//
//class D : public B, public C
//{
//public:
//	virtual void func4() { cout << "D::func4" << endl; }
//
//	int _d;
//};
//
////int main()
////{
////	D d;
////	cout << sizeof(d) << endl;
////
////	// 结论菱形继承的对象模型跟多继承类似
////	d.B::_a = 1;
////	d.C::_a = 2;
////	d._b = 3;
////	d._c = 4;
////	d._d = 5;
////
////	return 0;
////}
//
//int main()
//{
//	D d;
//	cout << sizeof(d) << endl;
//
//	// 结论菱形虚拟继承的对象模型跟多继承类似
//	d.B::_a = 1;
//	d.C::_a = 2;
//	d._b = 3;
//	d._c = 4;
//	d._d = 5;
//
//	return 0;
//}

using namespace std;
class A {
public:
	A(const char* s) { cout << s << endl; }
	~A() {}
};

class B :virtual public A
{
public:
	B(const char* s1, const char* s2) :A(s1) { cout << s2 << endl; }
};

class C :virtual public A
{
public:
	C(const char* s1, const char* s2) :A(s1) { cout << s2 << endl; }
};

class D :public B, public C
{
public:
	D(const char* s1, const char* s2, const char* s3, const char* s4)
		:B(s1, s2)  //A  B
		,C(s1, s3)  //A  C
		,A(s1)      //A
	{
		// D
		cout << s4 << endl;
	}
};

// 21:05
// 不要写菱形虚拟继承，大坑特坑
//  class A  class B  class C  class D
//  class B  class C  class A  class D
//  class A  class B class A  class C  class A  class D

//int main() {
//	D* p = new D("class A", "class B", "class C", "class D");
//	delete p;
//
//	return 0;
//}

